package com.example.designmode.proxy.cglibproxy

import com.example.designmode.proxy.staticproxy.SellPackets
import com.example.designmode.proxy.staticproxy.TrainStation
import net.sf.cglib.proxy.Enhancer
import net.sf.cglib.proxy.MethodInterceptor
import net.sf.cglib.proxy.MethodProxy
import java.lang.reflect.Method


/**
 * CGLIB代理工厂类
 * 说明：因为Kotlin的class 默认是final的， fun 默认也是final的，cglib对final的方法，是不走Proxy callback的。
 *
 * @author zhouronghua
 * @time 2022/3/10 8:54 下午
 */
class CGProxyFactory : MethodInterceptor {

    val trainStation: TrainStation = TrainStation()

    fun getProxyObject(): SellPackets {
        // 创建Enhancer对象，类似于JDK 代理中的Proxy
        val enhancer = Enhancer()
        // 设置父类的字节码对象
        enhancer.setSuperclass(trainStation.javaClass)
        // 设置回调函数
        enhancer.setCallback(this)
        // 创建代理对象
        val proxyObject: TrainStation = enhancer.create() as TrainStation
        return proxyObject
    }

    /**
     * 这个方法什么时候执行
     * 这个接口只有一个intercept()方法，这个方法有4个参数：
     * 1）obj表示增强的对象，即实现这个接口类的一个对象；
     * 2）method表示要被拦截的方法；
     * 3）args表示要被拦截方法的参数；
     * 4）proxy表示要触发父类的方法对象；
     *
     * @author zhouronghua
     * @time 2022/3/10 9:07 下午
     */
    override fun intercept(
        obj: Any?,
        method: Method?,
        args: Array<out Any>?,
        methodProxy: MethodProxy?
    ): Any? {
        println("代售点进行卖票处理。。。")
        val result = methodProxy?.invokeSuper(obj, args)
        println("插入后置通知。。。")
        return result
    }
}